﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MossmanMill.DataModel;

namespace MossmanMill
{
    public partial class LookupForm : Form
    {
        private List<Rack> racks;
        private List<Card> cards;
        private List<Sensor> sensors;
        private List<NetworkCard> nCards;
        private List<Processor> processors;
        private List<Room> rooms;
        private Type filter;

        private Room roomFilter;
        private Rack rackFilter;
        private Card cardFilter;
        private MainForm mainform;
        private object selection;

        enum Type
        {
            RACK, CARD, SENSOR, NETWORK, PROCESSOR, ROOM
        }

        public LookupForm(MainForm form)
        {
            mainform = form;
            InitializeComponent();
            RackBtn.Checked = true;
            LoadRacks();
        }

        private void LoadRooms()
        {
            filter = Type.ROOM;
            var db = DatabaseAccess.Instance;
            rooms = db.GetRooms();
            ModelComboBox.Items.Clear();
            foreach (var room in rooms)
            {
                ModelComboBox.Items.Add(room);
            }
        }

        private void LoadRacks()
        {
            filter = Type.RACK;
            var db = DatabaseAccess.Instance;
            racks = roomFilter == null ? db.GetRacks() : db.GetRacks(roomFilter.Id);
            ModelComboBox.Items.Clear();
            foreach (var rack in racks)
            {
                ModelComboBox.Items.Add(rack);
            }
        }

        private void LoadCards()
        {
            filter = Type.CARD;
            var db = DatabaseAccess.Instance;
            cards = rackFilter == null? db.GetCards() : db.GetCards(rackFilter); 
            ModelComboBox.Items.Clear();
            foreach (var card in cards)
            {
                ModelComboBox.Items.Add(card);
            }
        }

        private void LoadSensors()
        {
            filter = Type.SENSOR;
            var db = DatabaseAccess.Instance;
            sensors = cardFilter == null ? db.GetSensors() : db.GetSensors(cardFilter);
            ModelComboBox.Items.Clear();
            foreach (var card in sensors)
            {
                ModelComboBox.Items.Add(card);
            }
        }

        private void LoadNCards()
        {
            filter = Type.NETWORK;
            var db = DatabaseAccess.Instance;
            nCards = rackFilter == null ? db.GetNetworkCards() : db.GetNetworkCards(rackFilter);
            ModelComboBox.Items.Clear();
            foreach (var card in nCards)
            {
                ModelComboBox.Items.Add(card);
            }
        }

        private void LoadProcessors()
        {
            filter = Type.PROCESSOR;
            var db = DatabaseAccess.Instance;
            processors = rackFilter == null ? db.GetProcessors() : db.GetProcessors(rackFilter);
            ModelComboBox.Items.Clear();
            foreach (var card in processors)
            {
                ModelComboBox.Items.Add(card);
            }
        }

        private void ClickFilter(object sender, EventArgs e)
        {
            var radio = (RadioButton) sender;
            switch (radio.Text)
            {
                case "Racks":
                    SetFilterBtn.Enabled = true;
                    LoadRacks();
                    break;
                case "I/O Modules":
                    SetFilterBtn.Enabled = true;
                    LoadCards();
                    break;
                case "I/O Devices":
                    SetFilterBtn.Enabled = false;
                    LoadSensors();
                    break;
                case "Network Cards":
                    SetFilterBtn.Enabled = false;
                    LoadNCards();
                    break;
                case "Processors":
                    SetFilterBtn.Enabled = false;
                    LoadProcessors();
                    break;
                case "Rooms":
                    SetFilterBtn.Enabled = true;
                    LoadRooms();
                    break;
            }
            FlipButtons(radio);
        }

        private void FlipButtons(RadioButton radio)
        {
            RackBtn.Checked = radio == RackBtn;
            CardBtn.Checked = radio == CardBtn;
            SensorBtn.Checked = radio == SensorBtn;
            NetworkBtn.Checked = radio == NetworkBtn;
            ProcessorBtn.Checked = radio == ProcessorBtn;
            RoomBtn.Checked = radio == RoomBtn;
            FreeSpacePanel.Enabled = radio == CardBtn || radio == RackBtn;
            //{
            //    var database = new DBFactory().Make(DBFactory.CLASS_TYPE_DATABASE); //Get DB singleton
            //    Card card = database.GetCard(1); // Load Card
            //    var sensors = new Sensor[card.GetChannels()]; //Init sensor array
            //    foreach (var sensor in database.GetSensors(card)) sensors[sensor.Channel] = sensor; // Convert sensor list from DB into sensor array
            //    card.SetSensors(sensors); //set the card sensors to the sensor array
            //    foreach (var sensor in card.Sensors) ; //Do Something
            //}
            //{
            //    var database = new DBFactory().Make(DBFactory.CLASS_TYPE_DATABASE); //Get DB singleton
            //    Card card = database.GetCard(1); //Load Card
            //    foreach (var sensor in card.Sensors) ; //Do Something
            //}
        }

        private void SelectItem(object sender, EventArgs e)
        {
            var lines = new String[5];
            selection = ModelComboBox.SelectedItem;
            rackBrowserBtn.Enabled = selection != null;
            rackInputBtn.Enabled = selection != null;
            rackPlannerBtn.Enabled = !(selection is Room) && selection != null;
            switch (filter)
            {
                case Type.RACK:
                    var rack = (Rack)ModelComboBox.SelectedItem;
                    lines[0] = "Rack:";
                    lines[1] = rack.Model + " " + rack.Address;
                    lines[2] = rack.GetFreeSlots() + " Free Slots"; 
                    lines[3] = "Location: " + rack.Room.Name;
                    break;
                case Type.CARD:
                    var card = (Card)ModelComboBox.SelectedItem;
                    lines[0] = "I/O Module:";
                    lines[1] = card.Name;
                    lines[2] = card.GetChannels() + " CH " + Card.TypeToString(card.Type);
                    lines[3] = card.GetFreeChannels() + " Free Channels";
                    lines[4] = "Location: Slot " + card.Position + " on " + card.Rack.Model + " " + card.Rack.Address;
                    break;
                case Type.NETWORK:
                    var nCard = (NetworkCard)ModelComboBox.SelectedItem;
                    lines[0] = "Network Card:";
                    lines[1] = nCard.Model;
                    lines[2] = "Location: Slot " + nCard.Position + " on " + nCard.Rack.Model + " " + nCard.Rack.Address;
                    break;
                case Type.PROCESSOR:
                    var pCard = (Processor)ModelComboBox.SelectedItem;
                    lines[0] = "Processor:";
                    lines[1] = pCard.Model;
                    lines[2] = "Location: Slot " + pCard.Position + "/" + (pCard.Position+1) + " on " + pCard.Rack.Model + " " + pCard.Rack.Address;
                    break;
                case Type.SENSOR:
                    var sensor = (Sensor)ModelComboBox.SelectedItem;
                    lines[0] = "I/O Device:";
                    lines[1] = sensor.Tag + " " + sensor.Param;
                    lines[2] = sensor.Desc;
                    lines[3] = "Location: CH " + sensor.Channel + " on " + sensor.Card.Name;
                    lines[4] = "Slot " + sensor.Card.Position + " on " + sensor.Card.Rack.Model + " " + sensor.Card.Rack.Address;
                    break;
                case Type.ROOM:
                    var room = (Room)ModelComboBox.SelectedItem;
                    lines[0] = "Room";
                    lines[1] = room.Name;
                    lines[2] = room.Racks.Count + " Racks";
                    break;
            }
            InfoBox.Lines = lines;
        }

        private void ApplyFilter(object sender, EventArgs e)
        {
            if (ModelComboBox.SelectedItem == null) return;
            switch (filter)
            {
                case Type.ROOM:
                    roomFilter = (Room) ModelComboBox.SelectedItem;
                    RoomFilterLbl.Text = roomFilter.Name;
                    break;
                case Type.RACK:
                    rackFilter = (Rack) ModelComboBox.SelectedItem;
                    RackFilterLbl.Text = rackFilter.Model + " " + rackFilter.Address;
                    break;
                case Type.CARD:
                    cardFilter = (Card) ModelComboBox.SelectedItem;
                    CardFilterLbl.Text = cardFilter.Name;
                    break;
            }
        }

        private void ClearRoomFilter(object sender, EventArgs e)
        {
            roomFilter = null;
            RoomFilterLbl.Text = "No Filter";
            if (filter == Type.ROOM) LoadRooms();
        }

        private void ClearRackFilter(object sender, EventArgs e)
        {
            rackFilter = null;
            RackFilterLbl.Text = "No Filter";
            if (filter == Type.RACK) LoadRacks();
        }

        private void ClearCardFilter(object sender, EventArgs e)
        {
            cardFilter = null;
            CardFilterLbl.Text = "No Filter";
            if (filter == Type.CARD) LoadCards();
        }

        private void FindFreeSlots(object sender, EventArgs e)
        {
            int minSlots = (int)FreeSlotNum.Value;
            var dbFactory = new DBFactory();
            var db = dbFactory.Make(DBFactory.CLASS_TYPE_DATABASE);
            switch (filter)
            {
                case Type.CARD:
                    cards = rackFilter == null? db.GetCards() : db.GetCards(rackFilter); 
                    ModelComboBox.Items.Clear();
                    foreach (var card in cards)
                    {
                        if (card.GetFreeChannels() >= minSlots) ModelComboBox.Items.Add(card);
                    }
                    break;
                case Type.RACK:
                    racks = roomFilter == null ? db.GetRacks() : db.GetRacks(roomFilter.Id);
                    ModelComboBox.Items.Clear();
                    foreach (var rack in racks)
                    {
                        if (rack.GetFreeSlots() >= minSlots) ModelComboBox.Items.Add(rack);
                    }
                    break;
            }
        }

        private void rackPlannerBtn_Click(object sender, EventArgs e)
        {
            if (selection == null) return;
            RackPlanner.RackPlanner form = new RackPlanner.RackPlanner(mainform);
            if (selection is Card) form.LoadCard((Card)selection);
            if (selection is Rack) form.LoadRack((Rack)selection);
            if (selection is Sensor) form.LoadSensor((Sensor)selection);
            if (selection is NetworkCard) form.LoadRack(((NetworkCard)selection).Rack);
            if (selection is Processor) form.LoadRack(((Processor)selection).Rack);
            form.Show();
        }

        private void rackInputBtn_Click(object sender, EventArgs e)
        {
            if (selection == null) return;
            DataInputForm form = new DataInputForm();
            if (selection is Card) form.LoadCard((Card)selection);
            if (selection is Rack) form.LoadRack((Rack)selection);
            if (selection is Sensor) form.LoadSensor((Sensor)selection);
            if (selection is NetworkCard) form.LoadRack(((NetworkCard)selection).Rack);
            if (selection is Processor) form.LoadRack(((Processor)selection).Rack);
            if (selection is Room) form.LoadRoom((Room)selection);
            form.Show();
        }

        private void rackBrowserBtn_Click(object sender, EventArgs e)
        {
            var form = mainform;
            if (selection is Card) form.LoadCard((Card)selection);
            if (selection is Rack) form.LoadRack((Rack)selection);
            if (selection is Sensor) form.LoadCard(((Sensor)selection).Card);
            if (selection is NetworkCard) form.LoadRack(((NetworkCard)selection).Rack);
            if (selection is Processor) form.LoadRack(((Processor)selection).Rack);
            if (selection is Room) form.InitRoom((Room)selection);
            mainform.Invalidate();
            this.Close();
        }
    }
}
